package com.alan.android.sqlite.table;

import static com.alan.android.sqlite.constant.Constants.DB_TAG;

import android.content.ContentValues;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;

import com.alan.android.sqlite.converters.ColumnConverterFactory;
import com.alan.android.sqlite.converters.IColumnConverter;
import com.alan.android.sqlite.reflect.ObjectFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class TableHelper {

    public static synchronized ContentValues getContentValues(Object t,Table table) {
        ContentValues contentValues = new ContentValues();
        Collection<Column> values = table.getColumns().values();
        for (Column column : values) {
            String value = getValue(t, column);
            if (column.isAutoIncrement() && (TextUtils.isEmpty(value) || "0".equals(value))) {
                continue;
            }
            Log.d(DB_TAG, "[getContentValues] "+column.getName() + ":" + value +" isAutoIncrement:"+column.isAutoIncrement());
            contentValues.put(column.getName(), value);
        }
        return contentValues;
    }

    public static synchronized String[] whereArgs(Object t,Table table,StringBuilder stringBuilder, String... columns) {
        List<String> list = new ArrayList<>();
        if (columns == null) {
            Collection<Column> values = table.getColumns().values();
            for (Column column : values) {
                if (column.isPrimaryKey()) {
                    if (stringBuilder.length() > 0) {
                        stringBuilder.append(" and ");
                    }
                    stringBuilder.append(column.getName()).append("=?");
                    list.add(getValue(t, column));
                }
            }

        } else {
            Map<String, Column> map = table.getColumns();
            for (String columnStr : columns) {
                Column column = map.get(columnStr);
                if (stringBuilder.length() > 0) {
                    stringBuilder.append(" and ");
                }
                stringBuilder.append(columnStr).append("=?");
                list.add(getValue(t, column));
            }
        }
        String[] array = new String[list.size()];
        list.toArray(array);
        return array;
    }

    public static synchronized <T> T getModelByCursor(Table table, Cursor cursor, ObjectFactory<T> objectFactory) throws Exception {
        T t = objectFactory.newInstance();
        Map<String, Column> map = table.getColumns();
        for (int columnIndex = 0, count = cursor.getColumnCount(); columnIndex < count; columnIndex++) {
            String columnName = cursor.getColumnName(columnIndex);
            // 通过字段名字得到对应的java类中的字段
            Column column = map.get(columnName);
            if (column != null) {
                // 得到字段的转化器
                IColumnConverter converter = column.getColumnConverter();
                // 从cursor中得到值
                Object value = converter.getDBType().getValueFromCursor(cursor, columnIndex);
                // 从sql类型的数据转化成java类保存的数据类型
                value = converter.toJavaValue(value);
                // 把value值设置在result实例里
                column.getColumnField().set(t, value);
            }
        }
        return t;
    }


    private static synchronized String getValue(Object t, Column column) {
        try {
            return convertToStringValues(column.getColumnField().get(t));
        } catch (IllegalAccessException e) {
            Log.w(DB_TAG, Log.getStackTraceString(e));
        }
        return "";
    }

    private static String convertToStringValues(Object value) {
        /**
         * 把绑定的值转化为 字符串形式的绑定的值，但是必须先进行转化器转化一下
         */
        // 得到对应类型的转化器
        IColumnConverter converter = ColumnConverterFactory.getColumnConverter(value);
        // 从java类型的数据转化成sql保存的数据类�?
        value = converter.toSqlValue(value);
        // 转化为字符串
        return String.valueOf(value);
    }

}
